package com.jrx.anytxn.param.job.tabank.config;

import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.common.uitl.JsonUtils;
import com.jrx.anytxn.param.config.AnytxnBatchProperties;
import com.jrx.anytxn.param.config.PathFileConfig;
import com.jrx.anytxn.param.constant.Constant;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.service.merge.IMergeBillingService;
import com.jrx.anytxn.param.service.merge.bean.MergeFile;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @program: anytxn-cf-parent
 * @description:
 * @author: xiaoyu.jing
 * @date: 2020-11-06 14:38
 **/
@Configuration
@EnableConfigurationProperties(AnytxnBatchProperties.class)
public class TaMergeBillingConfiguration {

    Logger logger = LoggerFactory.getLogger(this.getClass());


    @Resource(name = "paramSqlSessionFactory")
    SqlSessionFactory sqlSessionFactory;

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Autowired
    private IMergeBillingService mergeBillingService;

    @Autowired
    private PathFileConfig pathFileConfig;

    @Autowired
    private IOrganizationTableService organizationTableService;

    @Bean
    public Job taMergeBillingJob(){
        return jobBuilderFactory.get("taMergeBillingJob").incrementer(new RunIdIncrementer())
                .start(taMergeBillingStep())
                .build();
    }

    @Bean
    public Step taMergeBillingStep() {
        return stepBuilderFactory.get("taMergeBillingStep")
                .tasklet(taMergeBillingTasklet())
                .build();
    }

    private Tasklet taMergeBillingTasklet() {
        return (stepContribution, chunkContext) -> {
            List<MergeFile> mergeFileList = new ArrayList<>();
            PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(Constant.DEFAULT_ORG_NUMBER);
            String businessDate = DateUtils.format(org.getToday(),"yyyyMMdd");
            String mergeFilePage = pathFileConfig.getBasePath() + "/mergeFile/" + org.getTenantId();
            logger.info("科目流水表请求的目录为:{},业务日期为:{}", mergeFilePage, businessDate);

            File dirFile = new File(mergeFilePage);
            if (dirFile.exists()) {
                File[] files = dirFile.listFiles();
                for (File file : Objects.requireNonNull(files)) {
                    //如果遇到文件夹则递归调用。
                    if (!file.isDirectory() && file.getName().contains(businessDate) && file.getName().contains(".txt") && file.getName().contains("mergeFileBatch")) {
                        String mergeFilePagePah;
                        //如果传递过来的参数dirFile是以文件分隔符，也就是/或者\结尾，则如此构造
                        if (dirFile.getPath().endsWith(File.separator)) {
                            mergeFilePagePah = dirFile.getPath() + file.getName();
                        } else {
                            //否则，如果没有文件分隔符，则补上一个文件分隔符，再加上文件名，才是路径
                            mergeFilePagePah = dirFile.getPath() + File.separator + file.getName();
                        }
                        /* 读入TXT文件 */
                        InputStreamReader reader = new InputStreamReader(new FileInputStream(mergeFilePagePah), StandardCharsets.UTF_8); // 建立一个输入流对象reader
                        BufferedReader br = new BufferedReader(reader); // 建立一个对象，它把文件内容转成计算机能读懂的语言
                        String line = br.readLine();
                        while (line != null) {
                            MergeFile mergeFile = JsonUtils.json2pojo(line, MergeFile.class);
                            //判断是否有数据
                            if (mergeFile != null) {
                                mergeFileList.add(mergeFile);
                            }
                            line = br.readLine(); // 一次读入一行数据
                        }
                    }
                }
            }
            if (CollectionUtils.isNotEmpty(mergeFileList)) {
                List<MergeFile> mergeFiles = this.mergeMergeFileList(mergeFileList);
                mergeBillingService.dealMergeBilling(mergeFiles);

            }
            return RepeatStatus.FINISHED;
        };
    }

    /**
     * 根据科目号,借贷方向，费用码合并
     *
     * @param mergeFileList
     * @return
     */
    private List<MergeFile> mergeMergeFileList(List<MergeFile> mergeFileList) {
        List<MergeFile> mergeFiles = new ArrayList<>();
        //根据科目号合并集合的值
        mergeFileList.stream().collect(Collectors.groupingBy(TaMergeBillingConfiguration::fetchGroupKey)).forEach(
                (key, list) ->  {
                    BigDecimal amt = list.stream().map(MergeFile::getAmount).reduce(BigDecimal.ZERO,BigDecimal::add);
                    BigDecimal salesAmt = list.stream().map(MergeFile::getSalesAmt).reduce(BigDecimal.ZERO,BigDecimal::add);
                    MergeFile mergeFile = list.get(0);
                    mergeFile.setAmount(amt);
                    mergeFile.setSalesAmt(salesAmt);
                    mergeFiles.add(mergeFile);
                }
        );
        return mergeFiles;
    }

    private static String fetchGroupKey(MergeFile mergeFile){
        return mergeFile.getSubjectId() +"#"+ mergeFile.getSign()+"#"+mergeFile.getPriceTxaCode();
    }

}
